﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TripleClasses
{
    public class Triple : ICloneable, IComparable<Triple>
    {
        public Triple(int a, int b, int c)
        {
            A = a;
            B = b;
            C = c;
        }

        public int A { get; set; }
        public int B { get; set; }
        public int C { get; set; }

        public static Triple operator +(Triple triple1, Triple triple2)
        {
            long a, b, c;
            a = (long)triple1.A + triple2.A;
            b = (long)triple1.B + triple2.B;
            c = (long)triple1.C + triple2.C;
            if (a > (long)int.MaxValue || b > (long)int.MaxValue || c > (long)int.MaxValue)
            {
                throw new ArgumentOutOfRangeException("Sum exceeds int32 max value");
            }
            Triple result = new Triple((int)a, (int)b, (int)c);
            return result;
        }

        public static Triple operator -(Triple triple1, Triple triple2)
        {
            long a, b, c;
            a = (long)triple1.A - triple2.A;
            b = (long)triple1.B - triple2.B;
            c = (long)triple1.C - triple2.C;
            if (a < (long)int.MinValue || b < (long)int.MinValue || c < (long)int.MinValue)
            {
                throw new ArgumentOutOfRangeException("Difference deceeds int32 min value");
            }
            Triple result = new Triple((int)a, (int)b, (int)c);
            return result;
        }

        public static Triple operator ++(Triple triple)
        {
            long a, b, c;
            a = (long)triple.A;
            b = (long)triple.B;
            c = (long)triple.C;
            a++;
            b++;
            c++;
            if (a > (long)int.MaxValue || b > (long)int.MaxValue || c > (long)int.MaxValue)
            {
                throw new ArgumentOutOfRangeException("Sum exceeds int32 max value");
            }
            triple.A++;
            triple.B++;
            triple.C++;
            return triple;
        }

        public override string ToString()
        {
            return string.Format("({0}, {1}, {2})", A, B, C);
        }

        public object Clone()
        {
            return new Triple(A, B, C);
        }

        public override bool Equals(object obj)
        {
            Triple otherObj = (Triple)obj;
            return this.CompareTo(otherObj) == 0;
        }

        public int CompareTo(Triple other)
        {
            if (other == null)
            {
                throw new ArgumentNullException("Cannot compare to null object");
            }
            int difference = this.A - other.A + this.B - other.B + this.C - other.C;
            if (difference > 0)
            {
                return 1;
            }
            if (difference == 0)
            {
                return 0;
            }
            return -1;
        }
    }
}